package com.yunkeji.config.event.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yunkeji.api.user.mapper.ApiAppUserMapper;
import com.yunkeji.common.core.domain.event.LogininforEvent;
import com.yunkeji.common.core.domain.event.PayLogEvent;
import com.yunkeji.common.core.domain.event.PushOnlineEvent;
import com.yunkeji.common.core.domain.event.PushRollingEvent;
import com.yunkeji.common.enums.app.AppUserOnlineStatus;
import com.yunkeji.common.enums.app.EnableEnum;
import com.yunkeji.common.exception.AppServiceException;
import com.yunkeji.common.msg.PushMessage;
import com.yunkeji.common.msg.bo.RollingMsg;
import com.yunkeji.config.event.service.LogEventService;
import com.yunkeji.dao.domain.AppUser;
import com.yunkeji.dao.domain.AppUserExt;
import com.yunkeji.dao.domain.PayLog;
import com.yunkeji.dao.domain.UserFocus;
import com.yunkeji.dao.domain.sys.SysLogininfor;
import com.yunkeji.dao.mapper.AppUserExtMapper;
import com.yunkeji.dao.mapper.PayLogMapper;
import com.yunkeji.dao.mapper.UserFocusMapper;
import com.yunkeji.dao.mapper.sys.SysLogininforMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 事件实现
 *
 * @author 老张
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class LogEventServiceImpl implements LogEventService {
    private final SysLogininforMapper baseMapper;
    private final ApiAppUserMapper apiAppUserMapper;
    private final AppUserExtMapper appUserExtMapper;
    private final PayLogMapper payLogMapper;
    private final UserFocusMapper userFocusMapper;
    /**
     * 记录登录信息
     *
     * @author 老张
     * @param logininforEvent 登录事件
     */
    @Override
    @Async
    @EventListener
    public void recordLogininfor(LogininforEvent logininforEvent) {
        // 插入数据
        LogininforEvent.Logininfor logininfor = logininforEvent.buildEvent();
        SysLogininfor sysLogininfor = BeanUtil.toBean(logininfor, SysLogininfor.class);
        insertLogininfor(sysLogininfor);
    }

    /**
     * 记录支付信息
     *
     * @author 老张
     * @param payLogEvent 支付事件
     */
    @Async
    @EventListener
    @Override
    public void payLogEvent(PayLogEvent payLogEvent) {
        log.info("支付日志事件->{}", payLogEvent.toString());
        Long userId = payLogEvent.getUserId();
        if (userId == null) {
            throw AppServiceException.paramException("用户id不能为空");
        }
        AppUser appUser = apiAppUserMapper.selectById(userId);
        AppUserExt appUserExt = appUserExtMapper.selectById(userId);
        if (appUser == null) {
            throw AppServiceException.paramException("用户查询失败");
        }
        PayLog payLog = BeanUtil.toBean(payLogEvent, PayLog.class);
        payLog.setPlatformId(appUser.getPlatformId());
        payLog.setNickName(appUserExt.getNickName());
        payLog.setHeadUrl(appUserExt.getHeadUrl());
        payLog.setPhone(appUser.getPhone());
        payLogMapper.insert(payLog);
    }

    @Override
    @Async
    @EventListener
    public void pushRollingMsg(PushRollingEvent pushRollingEvent) {
        List<AppUser> appUsers =
                apiAppUserMapper.selectList(
                        Wrappers.lambdaQuery(AppUser.class)
                                .select(AppUser::getPlatformId)
                                .ne(AppUser::getOnlineStatus, AppUserOnlineStatus.离线.getCode()));
        if (appUsers.size() > 0) {
            List<Long> collect =
                    appUsers.stream().map(AppUser::getPlatformId).collect(Collectors.toList());
            PushMessage.sendRollingMsg(
                    collect,
                    RollingMsg.builder()
                            .type(pushRollingEvent.getType())
                            .content(
                                    pushRollingEvent.getContent() != null
                                            ? pushRollingEvent.getContent().toString()
                                            : null)
                            .nickname(pushRollingEvent.getNickName())
                            .headUrl(pushRollingEvent.getHeadUrl())
                            .build());
        }
    }

    /**
     * 推送关注人
     *
     * @author 老张
     */
    @Async
    @EventListener
    @Override
    public void pushOnlineMsg(PushOnlineEvent pushOnlineEvent) {
        Long uid = pushOnlineEvent.getUid();
        List<UserFocus> userFoci =
                userFocusMapper.selectList(
                        Wrappers.lambdaQuery(UserFocus.class)
                                .select(UserFocus::getFansPlatformId)
                                .eq(UserFocus::getDelFlag, EnableEnum.NO.getCode())
                                .eq(UserFocus::getFocusUserId, pushOnlineEvent.getUid()));
        if (userFoci.size() > 0) {
            List<Long> collect =
                    userFoci.stream()
                            .map(UserFocus::getFansPlatformId)
                            .collect(Collectors.toList());
            PushMessage.sendLinkMsg(
                    collect, "您关注的用户上线了，快去聊聊吧~~【点击立即前往】", "chat/single?userId=" + uid);
        }
    }

    private void insertLogininfor(SysLogininfor logininfor) {
        logininfor.setLoginTime(new Date());
        baseMapper.insert(logininfor);
    }
}
